// import * as XLSX from 'xlsx';
import provincesJson from '@/assets/json/provinces.json';
import citiesJson from '@/assets/json/cities.json';
import areasJson from '@/assets/json/areas.json';
import pinyin from 'pinyin';
import dayjs from 'dayjs';
import { isJSON } from './isType';
import { ex } from '@fullcalendar/core/internal-common';

/**
 * 监听键盘ctrl+alt + 鼠标滚轮控制放大缩小事件
 * event 事件
 * enlarge 放大函数
 * shrink 缩小函数
 */
export function zoomWithMouse(event: any, enlarge: any, shrink: any) {
  if (event.ctrlKey && event.altKey) {
    if (event.deltaY > 0) {
      // 鼠标滚轮向后
      // 缩小页面的操作
      // 可以使用合适的缩小逻辑
      // 例如使用 document.body.style.zoom 或者改变元素的宽高等
      shrink();
    } else if (event.deltaY < 0) {
      // 鼠标滚轮前
      // 放大页面的操作
      // 可以使用合适的缩小逻辑
      // 例如使用 document.body.style.zoom 或者改变元素的宽高等
      enlarge();
    } else event.preventDefault(); // 阻止默认的滚动行为
  }
}

/**
 * 监听键盘ctrl+alt + 键盘+ - 号控制放大缩小事件
 * event 事件
 * enlarge 放大函数
 * shrink 缩小函数
 */
export function zoomWithPlusAndMinus(event: any, enlarge: any, shrink: any) {
  if (event.ctrlKey && event.altKey) {
    if (event.key === '+') {
      // 放大页面的操作
      // 可以使用合适的放大逻辑
      // 例如使用 document.body.style.zoom 或者改变元素的宽高等
      enlarge();
    } else if (event.key === '-') {
      // 缩小页面的操作
      // 可以使用合适的缩小逻辑
      // 例如使用 document.body.style.zoom 或者改变元素的宽高等
      shrink();
    } else event.preventDefault(); // 阻止默认的滚动行为
  }
}

// 时间戳转换
export function formatDate(cellValue: string | number) {
  if (cellValue === null || cellValue === '') return '';
  const date = new Date(cellValue);
  const year = date.getFullYear();
  const month =
    date.getMonth() + 1 < 10 ? `0${date.getMonth()}` : date.getMonth() + 1;
  const day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate();
  const hours = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours();
  const minutes =
    date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes();
  const seconds =
    date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds();
  // return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

// 将时间戳转换为标准时间
export function timeSwitch(time: number) {
  if (String(time).split('').length < 13) time *= 1000;
  time = Number(formatDate(time));
  return time;
}

// 获取当前的时间，年月日
export function getNowDate() {
  const date = new Date();
  const sign2 = ':';
  const year = date.getFullYear(); // 年
  let month: number | string = date.getMonth() + 1; // 月
  let day: number | string = date.getDate(); // 日
  // let hour = date.getHours(); // 时
  // let minutes = date.getMinutes(); // 分
  // let seconds = date.getSeconds() //秒
  const weekArr = [
    '星期一',
    '星期二',
    '星期三',
    '星期四',
    '星期五',
    '星期六',
    '星期天'
  ];
  const week = weekArr[date.getDay()];
  // 给一位数的数据前面加 “0”
  if (month >= 1 && month <= 9) {
    month = `0${month}`;
  }
  if (day >= 0 && day <= 9) {
    day = `0${day}`;
  }
  // if (hour >= 0 && hour <= 9) {
  //   hour = "0" + hour;
  // }
  // if (minutes >= 0 && minutes <= 9) {
  //   minutes = "0" + minutes;
  // }
  // if (seconds >= 0 && seconds <= 9) {
  //   seconds = "0" + seconds;
  // }
  // return year + "-" + month + "-" + day + " " + hour + sign2 + minutes + sign2 + seconds;
  return `${year}${month}${day}`;
}

/* 
  treeData: 传进来的树结构
  hasChild: 处理后的数组是否存在children字段， true 存在 false 不存在
*/
// 将树形结构扁平化不保留children
export function flatTree(treeData: any, hasChild = false) {
  let result: any = [];
  treeData.forEach((item: any) => {
    // 先克隆一份数据作为第一层级的填充
    const res = JSON.parse(JSON.stringify(item));
    if (!hasChild) delete res.children;
    result.push(res);
    if (item.children && item.children.length > 0) {
      // 如果当前children为数组并且长度大于0，才可进入flatTree()方法
      result = result.concat(flatTree(item.children, hasChild));
    }
  });
  return result;
}

/* 
  treeData: 传进来的树结构
  hasChild: 处理后的数组是否存在children字段， true 存在 false 不存在
*/
// 将树形结构扁平化且保留children
export function flatTreeWithChildren(treeData: any, hasChild = false) {
  let result: any = [];
  treeData.forEach((item: any) => {
    // 先克隆一份数据作为第一层级的填充
    const res = JSON.parse(JSON.stringify(item));
    // if (!hasChild) delete res.children;
    result.push(res);
    if (item.children && item.children.length > 0) {
      // 如果当前children为数组并且长度大于0，才可进入flatTree()方法
      result = result.concat(flatTreeWithChildren(item.children, hasChild));
    }
  });
  return result;
}

/**
 * 递归过滤节点，但保留原树结构，即符合条件节点的父路径上所有节点不管是否符合条件都保留
 * @param {Node[]} nodes 要过滤的树
 * @param {node => boolean} predicate 过滤条件，符合条件的节点保留(参数为函数，返回值为布尔值)
 * @param {node => boolean} wrapMatchFn 层级条件(参数为函数，返回值为布尔值)
 * @return 过滤后的包含根节点数组
 */
export const filterSearchTree = (
  nodes: any,
  predicate: any,
  wrapMatchFn = () => false
) => {
  // 如果已经没有节点了，结束递归
  if (!(nodes && nodes.length)) {
    return [];
  }
  const newChildren = [];
  for (let i = 0; i < nodes.length; i++) {
    const node: any = nodes[i];
    // 想要截止匹配的那一层（如果有匹配的则不用递归了，直接取下面所有的子节点）
    if (wrapMatchFn(node) && predicate(node)) {
      newChildren.push(node);
      continue;
    }
    const subs = filterSearchTree(node.children, predicate, wrapMatchFn);

    // 以下两个条件任何一个成立，当前节点都应该加入到新子节点集中
    // 1. 子孙节点中存在符合条件的，即 subs 数组中有值
    // 2. 自己本身符合条件
    if ((subs && subs.length) || predicate(node)) {
      node.children = subs || [];
      newChildren.push(node);
    }
  }
  return newChildren.length ? newChildren : [];
};

// 重新组合树数据(根据需要来重组树结构中的属性字段，用来新增判断是否为叶子节点信息)
export const dealTreeData = (treeData) => {
  const data = treeData.map((item) => ({
    ...item,
    // 新增title字段
    title: item.name,
    // 新增叶子节点字段
    isLeaf: item.children ? false : true,
    // 如果children为空数组，则置为null
    children:
      item.children && item.children.length ? dealTreeData(item.children) : null
  }));
  return data;
};

// 重组树形数据所需子方法
export const controldataTreeFilter = (treeData: any) => {
  // const temp = treeData.map((item2: any) => ({
  //   [item2.code]: item2.value
  // }));
  // let obj = {};
  // temp.forEach((item: any) => {
  //   obj = { ...obj, ...item };
  // });
  const temp = treeData.map((item2: any) => ({
    [item2.ctlCode]: item2.ctlValue
  }));
  let obj = {};
  temp.forEach((item: any) => {
    obj = { ...obj, ...item };
  });
  return obj;
};

/* 
重组树形属性数据并结合表头设置
  treeData: 传进来的树结构
  enable: 传进来的是否启用字段名，用于是否disabled选择
  level: 子树的层级
*/

export const dataTreeFilter = (
  treeData: any,
  enable: string | undefined = 'enable',
  level = 1
) => {
  const tempLevel = level;
  const data = treeData.map((item: any, index1: any) => {
    let disabled = false;
    if (enable && item[enable] === 2) disabled = true;
    return {
      ...item,
      ...controldataTreeFilter(item.ctlValue),
      selectable: !disabled,
      disabled,
      level,
      children:
        item.children && item.children.length
          ? dataTreeFilter(item.children, enable, tempLevel + 1)
          : null
    };
  });
  return data;
};

export const dataFilter = (data: any) => {
  console.log(data);

  const arr = data.map((item: any, index1: any) => ({
    ...item,
    ...controldataTreeFilter(item.positionDetailData)
  }));
  return arr;
};

// 树形结构单条件模糊搜索
export const mapTree = (value, arr) => {
  const newarr: any = [];
  arr.forEach((element) => {
    if (element.title.indexOf(value) > -1) {
      // 判断条件
      newarr.push(element);
    } else {
      if (element.children && element.children.length > 0) {
        const redata = mapTree(value, element.children);
        if (redata && redata.length > 0) {
          const obj = {
            ...element,
            children: redata
          };
          newarr.push(obj);
        }
      }
    }
  });
  return newarr;
};

// 剪切地区代码，分成省市区
export const placeSplice = (placeCode: string) => {
  const province = placeCode.slice(0, 2); // 剪切前两位
  const city = placeCode.slice(0, 4); // 剪切前四位
  const area = placeCode.slice(); // 剪切全部
  if (!placeCode) return '';
  const { name: provinceName }: any = provincesJson.find(
    (item: any) => item.code === province
  );

  const { name: cityName }: any = citiesJson.find(
    (item: any) => item.code === city
  );

  // 如果是省市区则placeCode为6
  if (placeCode.length === 6) {
    const { name: areaName }: any = areasJson.find(
      (item: any) => item.code === area
    );
    return `${provinceName}${cityName}${areaName}`;
  }

  return `${provinceName}${cityName}`;
};

/* 
  导出或下载excel文件
  imcomeFile 传进来的file文件
  name 导出文件的名称
*/
export const downloadExcelFile = (imcomeFile: any, name: string) => {
  const file = new Blob([imcomeFile], { type: 'application/xlsx' });
  console.log('file', file, imcomeFile);
  // const fileName = 'filename.xlsx';
  // if ('download' in document.createElement('a')) {
  //   // 非IE下载
  //   const link = document.createElement('a');
  //   link.download = fileName;
  //   link.style.display = 'none';
  //   link.href = URL.createObjectURL(file);
  //   document.body.appendChild(link);
  //   link.click();
  //   URL.revokeObjectURL(link.href); // 释放URL 对象
  //   document.body.removeChild(link);
  // } else {
  //   // IE10+下载
  //   navigator.msSaveBlob(file);
  // }

  const changeUrl = window.webkitURL.createObjectURL(file);
  let downloadElement: any = document.createElement('a');
  downloadElement.download = `${name}.xlsx`;
  downloadElement.href = changeUrl;
  downloadElement.click();
  downloadElement = undefined;
  window.URL.revokeObjectURL(changeUrl);
};

// 扁平化含有children的数组
export function flattenArrayWithChildren(arr: any[]) {
  return arr.reduce((flatArray: any[], item: any) => {
    if (item.children) {
      flatArray.push(item);
      flatArray.push(...flattenArrayWithChildren(item.children));
    } else {
      flatArray.push(item);
    }
    return flatArray;
  }, []);
}

// 转换人员列表，将人员列表按名字首字母排列， 其中数字和emoji及其他特殊符号在数组最后
export function sortContactsForGroupChat(contacts: Array<any>): Array<any> {
  // 比较名称
  function getNameForComparison(name: string): string {
    if (/^\d/.test(name) || /^[\uD800-\uDBFF]/.test(name)) {
      return '#';
    }
    const pinyinName = pinyin(name, { style: pinyin.STYLE_NORMAL });
    return pinyinName[0][0].toUpperCase();
  }

  // 获取首字母， 数字和emoji表情首位的都放在#的数组里面
  function getFirstLetter(name: string): string {
    if (/^\d/.test(name) || /^[\uD800-\uDBFF]/.test(name)) {
      return '#';
    }
    const pinyinName = pinyin(name, { style: pinyin.STYLE_FIRST_LETTER });
    return pinyinName[0][0].toUpperCase();
  }

  // nickname > username > name
  const sortedContacts = contacts.sort((a, b) => {
    const nameA = getNameForComparison(
      a.nickname ? a.nickname : a.username ? a.username : a.name
    );
    const nameB = getNameForComparison(
      a.nickname ? a.nickname : a.username ? a.username : a.name
    );

    // 如果其中一个姓名以数字或 emoji 开头，则将其放在后面
    if (
      (/^\d/.test(nameA) || /^[\uD800-\uDBFF]/.test(nameA)) &&
      !(/^\d/.test(nameB) || /^[\uD800-\uDBFF]/.test(nameB))
    ) {
      return 1;
    }
    if (
      (/^\d/.test(nameB) || /^[\uD800-\uDBFF]/.test(nameB)) &&
      !(/^\d/.test(nameA) || /^[\uD800-\uDBFF]/.test(nameA))
    ) {
      return -1;
    }

    return nameA.localeCompare(nameB);
  });

  const groupedContacts = {};
  sortedContacts.forEach((contact) => {
    const firstLetter = getFirstLetter(contact.name);
    if (!groupedContacts[firstLetter]) {
      groupedContacts[firstLetter] = [];
    }
    groupedContacts[firstLetter].push(contact);
  });

  // 将 # 分组放在最后
  const sortedGroupedContacts = {};
  const keys = Object.keys(groupedContacts).sort();
  const index = keys.indexOf('#');
  if (index !== -1) {
    keys.splice(index, 1);
    keys.push('#');
  }
  keys.forEach((letter) => {
    sortedGroupedContacts[letter] = groupedContacts[letter];
  });

  // 将联系人对象转换为数组
  const sortedGroupedContactsArray = Object.entries(sortedGroupedContacts).map(
    ([letter, contacts]) => ({
      letter,
      contacts
    })
  );
  return sortedGroupedContactsArray;
}

/**
 *比较相差的分钟数
 * @param date1 时间1
 * @param date2 时间2
 * @param thresholdType 相差类型
 * @param thresholdNum 相差时间
 * @returns boolean
 */
export function compareTime(
  date1: any,
  date2: any,
  thresholdType: 'day' | 'hour' | 'minute' | 'second',
  thresholdNum: number
) {
  date1 = dayjs(date1).format('YYYY-MM-DD HH:mm:ss');
  date2 = dayjs(date2).format('YYYY-MM-DD HH:mm:ss');
  const diffMinutes = Math.abs(dayjs(date1).diff(dayjs(date2), 'minute'));
  return diffMinutes > thresholdNum;
}
// 树形结构多条件模糊搜索
// export const matchTreeData = (arr, searchCon) => {
//   const newArr: any = [];
//   const searchNameList = ['name', 'code', 'title'];
//   arr.forEach((item: any) => {
//     for (let i = 0, len = searchNameList.length; i < len; i++) {
//       const nameKey = searchNameList[i];
//       if (item.hasOwnProperty(nameKey)) {
//         if (item[nameKey] && item[nameKey].indexOf(searchCon) !== -1) {
//           newArr.push(item);
//           break;
//         } else {
//           if (item.childList && item.childList.length > 0) {
//             const resultArr = this.matchTreeData(item.childList, searchCon);
//             if (resultArr && resultArr.length > 0) {
//               newArr.push({
//                 ...item,
//                 childList: resultArr
//               });
//               break;
//             }
//           }
//         }
//       } else {
//         continue;
//       }
//     }
//   });
//   return newArr;
// };

// 导出excel
/*
    * @description:
    * @param {Object} json 服务端发过来的数据
    * @param {String} name 导出Excel文件名字

    * @param {String} titleArr 导出Excel表头

    * @param {String} sheetName 导出sheetName名字
    * @return:
    */
// export function exportExcel(json, name, titleArr, sheetName) {
//   /* convert state to workbook */
//   console.log(json);

//   let data = new Array();
//   let keyArray = new Array();
//   const getLength = function (obj) {
//     let count = 0;
//     for (let i in obj) {
//       if (obj.hasOwnProperty(i)) {
//         count++;
//       }
//     }
//     return count;
//   };
//   for (const key1 in json) {
//     // console.log(key1 + 'a');

//     if (json.hasOwnProperty(key1)) {
//       const element = json[key1];
//       let rowDataArray = new Array();
//       for (const key2 in element) {
//         if (element.hasOwnProperty(key2) && key2 !== 'id') {
//           const element2 = element[key2];
//           rowDataArray.push(element2);
//           if (keyArray.length < getLength(element)) {
//             keyArray.push(key2);
//           }
//         }
//       }
//       data.push(rowDataArray);
//     }
//   }
//   // keyArray为英文字段表头
//   // data.splice(0, 0, keyArray,titleArr);
//   data.splice(0, 0,titleArr);
//   console.log('data', data);
//   const ws = XLSX.utils.aoa_to_sheet(data);
//   const wb = XLSX.utils.book_new();
//   // 此处隐藏英文字段表头
//   // let wsrows = [{ hidden: true }];
//   // ws['!rows'] = wsrows; // ws - worksheet
//   XLSX.utils.book_append_sheet(wb, ws, sheetName);
//   /* generate file and send to client */
//   XLSX.writeFile(wb, name + '.xlsx');
// }
/**
 * 获取试用期考核状态名称
 * @param type
 * @returns
 */
export function getProbationExamineStatusName(type: number) {
  switch (type) {
    case 1:
      return '待创建';
    case 2:
      return '待提交';
    case 3:
      return '待确认';
    case 4:
      return '已退回';
    case 5:
      return '已生效';
    case 6:
      return '变更中';
    case 7:
      return '变更中';
    case 8:
      return '待自评';
    case 9:
      return '待评分';
    case 10:
      return '结果待确认';
    case 11:
      return '已确认';
    case 12:
      return '结果拒绝';
    case 13:
      return '结果拒绝';
    case 14:
      return '方案不通过';
    case 15:
      return '结果申诉';
    case 16:
      return '已结束';
    case 17:
      return '已结束';
    case 18:
      return '申诉超时';
    case 19:
      return '已生效';
    case 20:
      return '已生效';
    default:
      return '无状态';
  }
}

/**
 * 将颜色变浅
 * @param color 颜色(例如#cccccc)
 * @param percent 百分比(变浅的百分比，例如20)
 */
export function lightenColor(color, percent) {
  const num = parseInt(color.slice(1), 16);
  const amt = Math.round(2.55 * percent);
  let r = (num >> 16) + amt;
  let b = ((num >> 8) & 0x00ff) + amt;
  let g = (num & 0x0000ff) + amt;
  r = Math.min(r, 255);
  g = Math.min(g, 255);
  b = Math.min(b, 255);
  const newColor =
    '#' + (g | (b << 8) | (r << 16)).toString(16).padStart(6, '0');
  return newColor;
}

// 格式化时间，用于工作台日历待办
export function formatTimeRange(today, startTime, endTime) {
  today = dayjs(today);
  const start = dayjs(startTime);
  const end = dayjs(endTime);
  if (start.isSame(end, 'minute')) {
    return `${start.format('YYYY-MM-DD HH:mm')}`;
  }

  if (start.isSame(today, 'day') && end.isSame(today, 'day')) {
    if (start.isSame(end, 'minute')) {
      return `${start.format('HH:mm')}`;
    } else {
      return `今日${start.format('HH:mm')}~今日${end.format('HH:mm')}`;
    }
  } else if (start.isSame(today, 'day')) {
    return `今日${start.format('HH:mm')}~${end.format('YYYY-MM-DD HH:mm')}`;
  } else if (end.isSame(today, 'day')) {
    return `${start.format('YYYY-MM-DD HH:mm')}~今日${end.format('HH:mm')}`;
  }
  // else if (start.isSame(end, 'day') && start.isSame(today, 'day')) {
  //   return `今日${start.format('HH:mm')}~今日${end.format('HH:mm')}`;
  // }
  else {
    return `${start.format('YYYY-MM-DD HH:mm')}~${end.format(
      'YYYY-MM-DD HH:mm'
    )}`;
  }
}

// 根据身份证计算年龄
export function getAgeFromIdCard(idCard) {
  // 假设身份证号码中出生日期的格式为yyyymmdd
  const birthYear = Number(idCard.substring(6, 10));
  const birthMonth = Number(idCard.substring(10, 12)) - 1; // 月份从0开始计数
  const birthDay = Number(idCard.substring(12, 14));

  const today = new Date();
  const birthDate = new Date(birthYear, birthMonth, birthDay);

  let age = today.getFullYear() - birthDate.getFullYear();
  if (
    today.getMonth() < birthDate.getMonth() ||
    (today.getMonth() === birthDate.getMonth() &&
      today.getDate() < birthDate.getDate())
  ) {
    age--;
  }
  return age;
}

//base64转blob
export const base64ToBlob = (code) => {
  const parts = code.split(';base64,');
  const contentType = parts[0].split(':')[1];
  const raw = window.atob(parts[1]);
  const rawLength = raw.length;
  const uInt8Array = new Uint8Array(rawLength);
  for (let i = 0; i < rawLength; ++i) {
    uInt8Array[i] = raw.charCodeAt(i);
  }
  return new Blob([uInt8Array], { type: contentType });
};
